package com.example.media.aspect;

import com.example.media.advice.MyException;
import com.example.media.constant.RedisKey;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import javax.servlet.http.HttpServletRequest;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Aspect
@Component
@Slf4j
public class NoRepeatSubmitAspect {

    private final RedisTemplate redisTemplate;

    public NoRepeatSubmitAspect(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }


    @Pointcut("execution(* com.example.media.controller.*.*(..))")
    public void log() {
    }

    @Around("log()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        HttpServletRequest request = getHttpServletRequest();
        // 此处可以用token或者JSessionId
        String token = request.getHeader("Authorization");
        if (token == null) {
            return pjp.proceed();
        }
        String path = request.getServletPath();
        String key = token + path + StringUtils.join(pjp.getArgs(), ",");
        Boolean aBoolean = redisTemplate.boundValueOps(RedisKey.RESUBMIT + key).setIfAbsent(UUID.randomUUID().toString(), 10, TimeUnit.SECONDS);
        if (!aBoolean) {
            throw new MyException("你请求的太快了，给我缓口气");
        } else {
            try {
                return pjp.proceed();
            } finally {
                redisTemplate.delete(RedisKey.RESUBMIT + key);

            }
        }
    }

    private HttpServletRequest getHttpServletRequest() {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        //从获取RequestAttributes中获取HttpServletRequest的信息
        return (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
    }

}